package sk.ygor.raynor.rebind.common

import sk.ygor.raynor.client.json.JSONSerializer.ParametrizedClassName
import com.google.gwt.core.ext.typeinfo.{JField, JClassType, JType}

trait GeneratorUtils {
  def parametrizedClassNameSourceCode(parametrizedClassName: ParametrizedClassName): String =
    """new ParametrizedClassName("%s", "%s", %s)""".format(
      parametrizedClassName.packageName,
      parametrizedClassName.simpleSourceName,
      "new ParametrizedClassName[] {" +
              parametrizedClassName.typeParameters.map(parametrizedClassNameSourceCode(_)).mkString(",") +
              "}"
      )

  def withDoubleQuotes(s: String) = '"' + s + '"'

  private def nul2Option[T](maybeNul: T): Option[T] =
    if (maybeNul == null)
      None
    else
      Some(maybeNul)


  implicit def richJClassType(jClassType: JClassType) = new RichJClassType(jClassType)

  class RichJClassType(jClassType: JClassType) {
    def getSourceNameWithoutPackage = jClassType.getQualifiedSourceName.substring(jClassType.getPackage.getName.length + 1)
  }

  implicit def richJClassType[T <: JType](jType: T) = new RichJType(jType)

  class RichJType(jType: JType) {
    def equalToJavaClass(clazz: Class[_]) = jType.getQualifiedSourceName == clazz.getName

    def maybeAnnotation = nul2Option(jType.isAnnotation())

    def maybeArray = nul2Option(jType.isArray())

    def maybeClass = nul2Option(jType.isClass())

    def maybeClassOrInterface = nul2Option(jType.isClassOrInterface())

    def maybeEnum = nul2Option(jType.isEnum())

    def maybeGenericType = nul2Option(jType.isGenericType())

    def maybeInterface = nul2Option(jType.isInterface())

    def maybeParameterized = nul2Option(jType.isParameterized())

    def maybePrimitive = nul2Option(jType.isPrimitive())

    def maybeRawType = nul2Option(jType.isRawType())

    def maybeTypeParameter = nul2Option(jType.isTypeParameter())

    def maybeWildcard = nul2Option(jType.isWildcard())

  }

  implicit def jField2rich(jField: JField) = new RichJField(jField)

  class RichJField(jField: JField) {
    def findAnnotation[T <: java.lang.annotation.Annotation](annotationClass: Class[T]) =
      nul2Option(jField.getAnnotation(annotationClass))
  }

}



